import 'dart:collection';

import 'package:flame/components.dart';
import 'package:freedom/page/mahjong/bloc/user_state.dart';
import 'package:freedom/page/mahjong/common/common_card.dart';
import 'package:freedom/page/mahjong/common/mahjong_context.dart';
import 'package:freedom/page/mahjong/event/snatch_bar_event.dart';
import 'package:freedom/page/mahjong/event/start_game_event.dart';
import 'package:freedom/page/mahjong/event/user_bar_event.dart';
import 'package:freedom/page/mahjong/event/user_bump_event.dart';
import 'package:freedom/page/mahjong/event/user_cell_event.dart';
import 'package:freedom/page/mahjong/event/user_export_card.dart';
import 'package:freedom/page/mahjong/event/user_state_event.dart';
import 'package:freedom/page/mahjong/event/user_swap_event.dart';
import 'package:freedom/page/mahjong/event/user_touch_card.dart';
import 'package:freedom/page/mahjong/event/user_win_event.dart';
import 'package:freedom/page/mahjong/util/user_location.dart';

typedef ExportCallBack = Function(List<CommonCard> allCard);
// 注意 所有的子类 只做UI更新 不做数据处理

/// 出牌区的抽象
abstract class AbstractHand extends PositionComponent {
  late UserState currentUserState;
  AbstractHand({
    super.position,
    super.size,
    super.anchor,
  }) {
    currentUserState = MahjongContext.getUserState(userDirection())!;
    initEvent(currentUserState);
  }
  // 摸牌信息
  Component? TOUCH_CARD;

  List<int>? handCardList;

// 选中的数据
  Set<CommonCard> HAND_CARD_SELECT = HashSet<CommonCard>();

  /// 获取第一张牌的位置
  Vector2 getHandFirstCardPoint() {
    return Vector2(0, 0);
  }

  Direction userDirection() {
    return Direction.BOTTOM;
  }

  /// 摸牌事件
  Component? addTouchCard(int? card) {
    return null;
  }

  /// 摸牌事件
  void addWinCard(int card);

  /// 出牌事件
  void exportCard(int? card, {ExportCallBack? callBack});

  Component? defaultAddTouchCard(int? card) {
    currentUserState.addTouchCard(card);
    return addTouchCard(card);
  }

  void defaultExportCard(int? card, {ExportCallBack? callBack}) {
    currentUserState.exportCardFunc(card);
    exportCard(card, callBack: callBack);
  }

  /// 手牌数量变更
  void handCardRefresh(int? card) {}

  /// 手牌碰杠信息变更
  void handTbCardRefresh(List<OpenDeal>? card) {}

  Future<void> reflashUI(UserState userState, {List<int>? highlight});

  /// type  1 明杠   手牌减少一张摸一张
  ///       2 暗杠   手牌减少4张 摸一张
  ///       3 点杠   手牌减少三张 摸一张
  void barCard(int card, int type) {}

  void addSwapCard(List<int>? swapCard) {
    currentUserState.addSwapCard(swapCard);
    reflashUI(currentUserState);
  }

  void removeSwapCard(List<int>? swapCard) {
    currentUserState.removeSwapCard(swapCard);
    reflashUI(currentUserState);
  }

  void defaultAddSwapCard(List<int>? swapCard) {
    addSwapCard(swapCard);
  }

  void defaultRemoveSwapCard(List<int>? swapCard) {
    removeSwapCard(swapCard);
  }

  void removeCard(int exportCard);

  void initEvent(UserState userStateParam) {
    // 用户出牌事件
    MahjongContext.registerUserFunc<UserExportCardEvent>(userStateParam.userId,
        (event) {
      // 清理mark标记
      MahjongContext.diskAllUser.forEach((key, value) {
        if (value.export.eportAllCard.isNotEmpty) {
          value.export.eportAllCard.last.removeMark();
        }
      });
      // 执行用户出牌事件
      defaultExportCard(event.cardCode, callBack: (allCard) {
        var index = allCard.length - 2;
        if (allCard.length > index && index >= 0) {
          allCard[index].removeMark();
        }
        allCard.last.addMark();
      });
    });
    // 用户摸牌事件
    MahjongContext.registerUserFunc<UserTouchCardEvent>(userStateParam.userId,
        (event) {
      currentUserState.touchCard = event.cardCode;
      currentUserState.touchCardAction = true;
      defaultAddTouchCard(event.cardCode);
      currentUserState.touchCardAction = false;
    });

    // 用户碰事件
    MahjongContext.registerUserFunc<UserBumpEvent>(userStateParam.userId,
        (event) {
      currentUserState.addOpenDeal(event.cardCode!, 1,
          sourceTarget: event.sourceBySeq);
      reflashUI(currentUserState);
      var exportUid = MahjongContext.roomInfo.gameInfo.exportUserId;
      MahjongContext.getUserStateById(exportUid)?.export.removeLastCard();
      MahjongContext.setUserState(userDirection(), currentUserState);
    });

    // 用户杠牌事件
    MahjongContext.registerUserFunc<UserBarEvent>(userStateParam.userId,
        (event) {
      currentUserState.addOpenDeal(event.cardCode!, event.cardType!,
          sourceTarget: event.sourceBySeq);
      if (event.cardType! == 4 && event.sourceBySeq != null) {
        MahjongContext.getUserStateBySeq(event.sourceBySeq!)
            ?.export
            .removeLastCard();
      }
      reflashUI(currentUserState);
    });

    // 用户胡牌事件
    MahjongContext.registerUserFunc<UserWinEvent>(userStateParam.userId,
        (event) {
      currentUserState.win = true;
      currentUserState.winCard = event.winCard;
      addWinCard(event.winCard);
      MahjongContext.setUserState(userDirection(), currentUserState);
    });

    // 用户拿出换牌事件
    MahjongContext.registerUserFunc<UserSwapEvent>(userStateParam.userId,
        (event) {
      currentUserState.waitCompleted = null;
      if (event.type == SwapState.IN) {
        var cardCount = currentUserState.getUserHandCards().length;
        if (cardCount == 13 || cardCount == 14) {
          return;
        }
        defaultAddSwapCard(event.swapCards);
      } else if (event.type == SwapState.OUT) {
        defaultRemoveSwapCard(event.swapCards);
      }
      MahjongContext.setUserState(userDirection(), currentUserState);
    });

    // 用户听牌事件
    MahjongContext.registerUserFunc<UserCellEvent>(userStateParam.userId,
        (event) {
      currentUserState.waitCompleted = null;
      currentUserState.listen = true;
      currentUserState.setListenCard(currentUserState.getUserHandCards());
      reflashUI(currentUserState);
    });
    // 用户状态变更
    MahjongContext.registerUserFunc<UserStateUpdateEvent>(userStateParam.userId,
        (event) {
      currentUserState = event.userState;
      reflashUI(currentUserState);
    });

    // 游戏开始
    MahjongContext.registerUserFunc<StartGameEvent>(userStateParam.userId,
        (event) {
      currentUserState = event.userState;
      currentUserState.startGaming = true;
      reflashUI(currentUserState);
      currentUserState.startGaming = false;
      MahjongContext.setUserState(userDirection(), currentUserState);
    });

    // 游戏开始
    MahjongContext.registerUserFunc<SnatchBarEvent>(userStateParam.userId,
        (event) {
      removeCard(event.cardCode);
    });
  }
}
